#include "beep.h"

#include "rtthread.h"

// 全局配置 - 可根据需要修改
TIM_HandleTypeDef *pwm_tim_handle = &htim2;  // 定时器句柄指针
uint32_t pwm_channel = TIM_CHANNEL_1;        // PWM通道

/**
 * @brief  初始化PWM输出（包括互补通道）
 * @retval HAL状态
 */
HAL_StatusTypeDef PWM_HAL_Init(void) {
    HAL_StatusTypeDef status;
    
    // 启动PWM通道
    status = HAL_TIM_PWM_Start(pwm_tim_handle, pwm_channel);
    if (status != HAL_OK) {
        return status;
    }
    
    // // 启动互补通道
    // status = HAL_TIMEx_PWMN_Start(pwm_tim_handle, pwm_channel);
    // return status;
}

/**
 * @brief  设置PWM频率（音调）并保持50%占空比
 * @param  tone: 音符对应的计数值
 * @retval None
 */
void PWM_HAL_Set_Tone(uint16_t tone) {
    // 设置自动重装载值（频率）
    __HAL_TIM_SET_AUTORELOAD(pwm_tim_handle, tone);
    
    // 设置比较值（50%占空比）
    __HAL_TIM_SET_COMPARE(pwm_tim_handle, pwm_channel, tone / 2);
    
    // 生成更新事件，使配置立即生效
    pwm_tim_handle->Instance->EGR = TIM_EGR_UG;
}

/**
 * @brief  播放指定音符
 * @param  note: 要播放的音符
 * @retval None
 */
void PWM_HAL_Play_Note(uint16_t note) {
    PWM_HAL_Set_Tone(note);
}

/**
 * @brief  停止PWM输出（静音）
 * @retval None
 */
void PWM_HAL_Stop(void) {
    // 将比较值设为0，停止输出
        __HAL_TIM_SET_AUTORELOAD(pwm_tim_handle, 1000);
    
    // 设置比较值（50%占空比）
    __HAL_TIM_SET_COMPARE(pwm_tim_handle, pwm_channel, 0);
    
    // 生成更新事件，使配置立即生效
    pwm_tim_handle->Instance->EGR = TIM_EGR_UG;
}

/**
 * @brief  调整PWM占空比
 * @param  duty: 占空比（0-100%）
 * @retval None
 */
void PWM_HAL_Set_Duty(uint8_t duty) {
    if (duty >= 0 && duty <= 100) {
        uint32_t arr = __HAL_TIM_GET_AUTORELOAD(pwm_tim_handle);
        __HAL_TIM_SET_COMPARE(pwm_tim_handle, pwm_channel, (arr * duty) / 100);
        
        // 生成更新事件
        pwm_tim_handle->Instance->EGR = TIM_EGR_UG;
    }
}

/**
 * @brief  暂停PWM输出
 * @retval HAL状态
 */
HAL_StatusTypeDef PWM_HAL_Pause(void) {
    HAL_StatusTypeDef status;
    
    // 停止PWM通道
    status = HAL_TIM_PWM_Stop(pwm_tim_handle, pwm_channel);
    if (status != HAL_OK) {
        return status;
    }
    
    // 停止互补通道
    status = HAL_TIMEx_PWMN_Stop(pwm_tim_handle, pwm_channel);
    return status;
}

/**
 * @brief  恢复PWM输出
 * @retval HAL状态
 */
HAL_StatusTypeDef PWM_HAL_Resume(void) {
    HAL_StatusTypeDef status;
    
    // 重启PWM通道
    status = HAL_TIM_PWM_Start(pwm_tim_handle, pwm_channel);
    if (status != HAL_OK) {
        return status;
    }
    
    // 重启互补通道
    status = HAL_TIMEx_PWMN_Start(pwm_tim_handle, pwm_channel);
    return status;
}

// 大疆开机提示音音符序列 (音高, 时长ms)
typedef struct {
    uint16_t note;   // 音符
    uint16_t duration; // 时长(ms)
} ToneSequence;

// 大疆开机提示音音符序列
const ToneSequence dji_powerup_sequence[] = {
    {NOTE_E5, 100},   // 第一个高音
    {REST, 30},       // 短暂停顿
    {NOTE_G5, 150},   // 第二个更高音
    {REST, 30},       // 短暂停顿
    {NOTE_C6, 200},   // 第三个最高音，持续稍长
    {REST, 50},       // 停顿
    {NOTE_G5, 100},   // 回落音
    // {REST, 20},       // 短暂停顿
    // {NOTE_E5, 300}    // 结束音，稍长
};

void play_dji_powerup_tone(void) {
    uint8_t i;
    uint16_t sequence_length;
    HAL_StatusTypeDef status;
    
    // 计算序列长度
    sequence_length = sizeof(dji_powerup_sequence) / sizeof(ToneSequence);
    
    // 依次播放每个音符
    for(i = 0; i < sequence_length; i++) {
        if(dji_powerup_sequence[i].note == REST) {
            // 休止符，停止输出
            PWM_HAL_Stop();
        } else {
            // 播放音符
            PWM_HAL_Set_Tone(dji_powerup_sequence[i].note);
        }
        
        // 保持当前音符指定的时长
        rt_thread_mdelay(dji_powerup_sequence[i].duration);
    }
    
    // 播放完毕，停止并暂停PWM
    PWM_HAL_Stop();
    // PWM_HAL_Pause();
}


